package com.smartstate.dataManagement.service.impl;

import ch.qos.logback.core.joran.util.beans.BeanUtil;
import com.alibaba.fastjson.JSON;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.smartstate.EnvironmentMonitor.dto.ReportDTO;
import com.smartstate.dataManagement.dto.EnergyDTO;
import com.smartstate.dataManagement.dto.PageDTO;
import com.smartstate.dataManagement.entity.Energy;
import com.smartstate.dataManagement.entity.EnergyReport;
import com.smartstate.dataManagement.mapper.EnergyReportMapper;
import com.smartstate.dataManagement.service.EnergyReportService;
import com.smartstate.dataManagement.util.BeanUtils;
import com.smartstate.dataManagement.util.StringUtils;
import org.springframework.stereotype.Service;

import javax.annotation.Resource;
import java.lang.reflect.Field;
import java.lang.reflect.Method;
import java.math.BigDecimal;
import java.math.RoundingMode;
import java.text.DecimalFormat;
import java.util.ArrayList;
import java.util.List;
import java.util.Locale;
import java.util.Map;
import java.util.stream.Collectors;

@Service
public class EnergyReportServiceImpl extends ServiceImpl<EnergyReportMapper, EnergyReport> implements EnergyReportService {

    @Resource
    private EnergyReportMapper energyReportMapper;

    @Override
    public Page<EnergyReport> queryAllPageByDTO(PageDTO pageDTO) {
        return null;
    }

    /**
     * 日报信息导出
     * @param energyDTO
     * @return
     */
    @Override
    public List<EnergyReport> exportExcel(EnergyDTO energyDTO) {
        String analysisObjectId = energyDTO.getAnalysisObject();
//        获取空间结构建模下的所有objId
        Map<String, Object> objectMap = energyReportMapper.queryAllObjId("1");
        if (objectMap == null || objectMap.size() == 0){
            return new ArrayList<>();
        }
//        递归获取analysisObjectId和analysisObjectId子集objId
        List<String> objIdList = new ArrayList<>();
        objIdList = acquireObjIds(objectMap, analysisObjectId, objIdList);
//        获取电表对应的所有设备
        List<EnergyReport> energyReports = energyReportMapper.queryExcelEneryDay(objIdList);
        DecimalFormat decimalFormat = new DecimalFormat("0.00");
        energyReports = assign(energyReports);
        List<EnergyReport> collect = energyReports.stream().map((item) -> {
//            获取指定期限的总电能
            String meterSum = energyReportMapper.queryMeterSum(energyDTO, item.getDeviceId());
            meterSum = meterSum == null ? "0.00" : meterSum;
            float meterSumFloat = Float.valueOf(meterSum);
            meterSumFloat = new BigDecimal(meterSumFloat).setScale(2, RoundingMode.DOWN).floatValue();
            //小数点不足两位添0
            meterSum = decimalFormat.format(meterSumFloat);
            item.setMeterSum(meterSum);
            return item;
        }).collect(Collectors.toList());
        return collect;
    }

    /**
     * 能耗日报查询
     * @param pageDTO
     * @return
     */
    @Override
    public IPage<EnergyReport> queryEneryDay(PageDTO pageDTO) {
        Page<EnergyReport> page = new Page<>();
//        偏移量
        long offset = (pageDTO.getPage() - 1) * pageDTO.getSize();
        EnergyDTO energyDTO = (EnergyDTO) pageDTO.getDto();
        String analysisObjectId = energyReportMapper.queryRootObjId("空间结构建模");
//        获取空间结构建模下的所有objId
        Map<String, Object> objectMap = energyReportMapper.queryAllObjId("1");
        if (objectMap == null || objectMap.size() == 0){
            return page;
        }
//        递归获取analysisObjectId和analysisObjectId子集objId
        List<String> objIdList = new ArrayList<>();
        objIdList = acquireObjIds(objectMap, analysisObjectId, objIdList);
//        获取电表对应的所有设备
        List<EnergyReport> energyReports = null;
        energyReports = energyReportMapper.queryEneryDay(pageDTO.getSize(), offset, objIdList);
        energyReports = assign(energyReports);
        DecimalFormat decimalFormat = new DecimalFormat("0.00");
        List<EnergyReport> collect = energyReports.stream().map((item) -> {
//            获取指定期限的总电能
            String meterSum = energyReportMapper.queryMeterSum(energyDTO, item.getDeviceId());
            meterSum = meterSum == null ? "0.00" : meterSum;
            float meterSumFloat = Float.valueOf(meterSum);
            meterSumFloat = new BigDecimal(meterSumFloat).setScale(2, RoundingMode.DOWN).floatValue();
            //小数点不足两位添0
            meterSum = decimalFormat.format(meterSumFloat);
            item.setMeterSum(meterSum);
            item.setDayStr(energyDTO.getStartTime());
            return item;
        }).collect(Collectors.toList());
        //        获取分页数
        long total = energyReportMapper.queryDeviceIdTotal(objIdList);
        long pages = (long) Math.ceil((double) total / page.getSize());
////        设置page属性
        page.setRecords(collect);
        page.setCurrent(pageDTO.getPage());
        page.setTotal(total);
        page.setPages(pages);
        page.setSize(pageDTO.getSize());
        return page;
    }

    /**
     * 递归获取analysisObjectId和analysisObjectId子集objId
     * @param objectMap
     * @param analysisObjectId
     * @return
     */
    public List<String> acquireObjIds(Map<String, Object> objectMap, String analysisObjectId, List<String> list) {
        list.add(analysisObjectId);
        try {
            for (String key : objectMap.keySet()) {
                Map map = (Map) objectMap.get(key);
                if (analysisObjectId.equals(map.get("parentId"))){
                    list = acquireObjIds(objectMap, key, list);
                }
            }
        }catch (Exception e){
            e.printStackTrace();
        }
        return list;
    }

    /**
     * 对属性赋值
     * @param energyReports
     * @return
     */
    public List<EnergyReport> assign(List<EnergyReport> energyReports){
        energyReports = energyReports.stream().map((item) -> {
            List<Map> lists = JSON.parseArray(item.getAdditionalAttribute(), Map.class);
            if (lists != null && lists.size() > 0){
                lists.forEach((s) -> {
                    item.setApplication(String.valueOf(s.get("use")));
                    item.setLocation(String.valueOf(s.get("location")));
                    item.setSystemName(String.valueOf(s.get("system")));
                    item.setStayguy(String.valueOf(s.get("wire")));
                    item.setTableName(String.valueOf(s.get("cabinet")));
                });
                BeanUtils.copyProperties(checkAttributeIsEmpty(item), item);
            }else {
                item.setTableName("暂未配置");
                item.setApplication("暂未配置");
                item.setLocation("暂未配置");
                item.setSystemName("暂未配置");
                item.setStayguy("暂未配置");
            }
            return item;
        }).collect(Collectors.toList());
        return energyReports;
    }

    /**
     * 判断值是否为空，若为空进行赋值
     * @param energyReport
     * @return
     */
    public EnergyReport checkAttributeIsEmpty(EnergyReport energyReport){
        Class<? extends EnergyReport> reportClass = energyReport.getClass();
        Field[] fields = reportClass.getDeclaredFields();
        for (Field field : fields) {
            field.setAccessible(true);
            String attributeName = field.getName();
            Class<?> attributeType = field.getType();
            String methodName = "set" + attributeName.substring(0, 1).toUpperCase() + attributeName.substring(1);
            try {
                if ("null".equals(field.get(energyReport)) || field.get(energyReport) == null || "".equals(field.get(energyReport))) {
                    Method method = reportClass.getMethod(methodName, attributeType);
                    method.invoke(energyReport, "暂未配置");
                }
            } catch (Exception e) {
                e.printStackTrace();
            }
        }
        return energyReport;
    }

}
